package walkera.cn.bean;

import android.graphics.Color;

import java.util.List;


@SuppressWarnings("WeakerAccess")
public class Square {
//    private   final int []  colors = {0xffe03636, 0xffedd0be, 0xffff534d, 0xff25c6fc};

    private enum Type {
        TYPE_0, TYPE_1, TYPE_2, TYPE_3, TYPE_4, TYPE_5, TYPE_6
    }

    public Type type;
    /**
     *  [4][2] , 每一个块，由四个格子组成，一个格子有x y 坐标
     */
    public int[][] cells;
    public int centerIndex;
    public int color;
    private IndexBound indexBound = new IndexBound();


    /**
     * 获得随机的  新方块
     */
    public static Square generate(int columns) {
        int randomIndex = (int) ( Math.random() * Type.values().length - 1);

        // 参数意义：刚生成时，7形状块 的 4个格子的信息。 例如 （-2 ，0） 代表这个格子是从第-2行，第1列开始往下掉落的
        int[][] TYPE_L =  {{-2, 0}, {-2, 1}, {-1, 1}, {0, 1}};
        Type type = Type.TYPE_0;;
        int[][] base =  TYPE_L ; ;
        int centerIndex = 0;

        //randomIndex= 0 ;
        switch (randomIndex) {
            case 0:
                type = Type.TYPE_0;
                base = TYPE_L ;
                centerIndex = 2;
                break;
            case 1:
                type = Type.TYPE_1;
                base = new int[][]{{-2, 1}, {-2, 0}, {-1, 0}, {0, 0}};
                centerIndex = 2;
                break;
            case 2:
                type = Type.TYPE_2;
                base = new int[][]{{-1, 1}, {0, 0},  {0, 1},  {0, 2}};
                centerIndex = 2;
                break;
            case 3:
                type = Type.TYPE_3;
                base = new int[][]{{-1, 0}, {-1, 1}, {-1, 2}, {-1, 3}};
                centerIndex = 2;
                break;
            case 4:

                type = Type.TYPE_4;
                base = new int[][]{{-1, 0}, {-1, 1}, {0, 0},  {0, 1}};
                break;
            case 5:
                type = Type.TYPE_5;
                base = new int[][]{{-1, 1}, {0, 1},  {0, 0},  {1, 0}};
                centerIndex = 1;
                break;
            case 6:
                type = Type.TYPE_6;
                base = new int[][]{{-1, 0}, {0, 0},  {0, 1},  {1, 1}};
                centerIndex = 1;
                break;

        }

        int [][] cells = new int[4][2];
        for (int i = 0; i < cells.length; i++) {
            cells[i][0] = base[i][0]; //  初始化格子的 所在行数
            cells[i][1] = base[i][1] + columns / 2 ; // 初始化格子的 所在列数
        }
        Square square = new Square();
//        square.color =  square.colors[(int) (Math.random() *  square.colors.length)];
        square.color = Color.parseColor("#000000");
        square.cells = cells;
        square.centerIndex = centerIndex;
        square.type = type;
        square.refreshBound();
        return square;
    }

    /**
     * 获取边界索引
     */
    private void refreshBound() {
        int left =   cells[0][1];
        int right =  cells[0][1];
        int top =    cells[0][0];
        int bottom = cells[0][0];

        int leftIndex = 0;
        int rightIndex = 0;
        int topIndex = 0;
        int bottomIndex = 0;
        for (int i = 0; i < cells.length; i++) {
            int[] point = cells[i];
            if (point[1] < left) {
                left = point[1];
                leftIndex = i;
            }
            if (point[1] > right) {
                right = point[1];
                rightIndex = i;
            }
            if (point[0] < top) {
                top = point[0];
                topIndex = i;
            }
            if (point[0] > bottom) {
                bottom = point[0];
                bottomIndex = i;
            }
        }
        indexBound.leftIndex = leftIndex;
        indexBound.rightIndex = rightIndex;
        indexBound.topIndex = topIndex;
        indexBound.bottomIndex = bottomIndex;
    }




    /**
     * 当前方块 是否还能继续往下掉落
     */
    public boolean canMoveDown(List<Cell> dst, int rows) {
        for (int i = 0; i < dst.size(); i++) {
            Cell cell = dst.get(i);
            if (checkDown(cell)) {
                return false;
            }
        }
        // 块中的最下面那个y坐标
        return cells[ indexBound.bottomIndex] [0] != rows - 1;
    }


    /**
     * 检查下边界 碰撞则返回true 。
     * 总的思路是： 用下落中的那个块中的每一个格子 ，分别与下面固定好的所有格子都比较一下。
     */
    private boolean checkDown(Cell cell) {
        for (int i = 0; i < cells.length; i++) {
            int[] first = cells[i];
            if (first[0] + 1 == cell.getRow() && first[1] == cell.getCol()) {
                return true;
            }
        }
        return false;
    }

    public int[][] canRotate(int deg, List<Cell> dst, int cols, int rows) {
        if (type == Type.TYPE_4) {
            return cells;
        }
        double d = Math.PI / 180 * deg;
        int temp[][] = new int[4][2];
        for (int i = 0; i < cells.length; i++) {
            int[] p = cells[i];
            double x = p[0] - cells[centerIndex][0];
            double y = p[1] - cells[centerIndex][1];
            double nx = x * Math.cos(d) - y * Math.sin(d);
            double ny = y * Math.cos(d) + x * Math.sin(d);

            temp[i][0] = (int) Math.round(nx + cells[centerIndex][0]);
            temp[i][1] = (int) Math.round(ny + cells[centerIndex][1]);
        }
//        int leftIndex = 0;
//        int rightIndex = 0;
//        int bottomIndex = 0;
        int left = temp[0][1];
        int right = temp[0][1];
        int bottom = temp[0][0];
        for (int i = 0; i < temp.length; i++) {
            int[] point = temp[i];
            if (point[1] < left) {
                left = point[1];
//                leftIndex = i;
            }
            if (point[1] > right) {
                right = point[1];
//                rightIndex = i;
            }
            if (point[0] > bottom) {
                bottom = point[0];
//                bottomIndex = i;
            }
        }
        //碰到底部
        if (bottom > rows - 1) {
            return null;
        }

        //出界归位
        if (left < 0) {
            for (int i = 0; i < temp.length; i++) {
                temp[i][1] += Math.abs(left);
            }
        } else if (right > cols - 1) {
            for (int i = 0; i < temp.length; i++) {
                temp[i][1] -= Math.abs(right - cols + 1);
            }
        }

        //碰到其他方块
        if (dst.size() > 0) {
            for (int i = 0; i < dst.size(); i++) {
                Cell cell = dst.get(i);
                if (checkRoateWithCell(temp, cell))
                    return null;
            }
        }
        return temp;
    }

    private boolean checkRoateWithCell(int[][] cells, Cell cell) {
        for (int i = 0; i < cells.length; i++) {
            int[] first = cells[i];
            if (first[0] == cell.getRow() && first[1] == cell.getCol()) {
                return true;
            }
        }
        return false;
    }

    /**
     * 逆时针旋转 90 度
     */
    public void rotate(  int[][] ints) {
        if (type == Type.TYPE_4) {
            return;
        }

        if (ints != null) {
            cells = ints;
            refreshBound();
        }
    }


    /**
     * 继续往下掉。
     * 往下掉，就是行+1 ， y坐标增大
     */
    public void move() {
        for (int i = 0; i < cells.length; i++) {
            int[] cell = cells[i];
            cell[0] = cell[0] + 1;
        }
    }

    //检查左边界 碰撞则返回true
    private boolean checkLeft(int[][] cells, Cell cell) {
        for (int i = 0; i < cells.length; i++) {
            int[] first = cells[i];
            if (first[0] == cell.getRow() && first[1] - 1 == cell.getCol()) {
                return true;
            }
        }
        return false;
    }

    public boolean canMoveLeft(List<Cell> dst) {
        for (int i = 0; i < dst.size(); i++) {
            Cell cell = dst.get(i);
            if (checkLeft(cells, cell)) {
                return false;
            }
        }
        return cells[indexBound.leftIndex][1] > 0;
    }

    public void moveLeft() {
        for (int i = 0; i < cells.length; i++) {
            int[] cell = cells[i];
            cell[1] = cell[1] - 1;
        }
    }

    //检查右边界 碰撞则返回true
    private boolean checkRight(int[][] cells, Cell cell, int cols) {
        for (int i = 0; i < cells.length; i++) {
            int[] first = cells[i];
            if (first[0] == cell.getRow() && first[1] + 1 == cell.getCol()) {
                return true;
            }
        }
        return false;
    }

    public boolean canMoveRight(List<Cell> dst, int cols) {
        for (int i = 0; i < dst.size(); i++) {
            Cell cell = dst.get(i);
            if (checkRight(cells, cell, cols)) {
                return false;
            }
        }
        return cells[indexBound.rightIndex][1] < cols - 1;
    }

    public void moveRight() {
        for (int i = 0; i < cells.length; i++) {
            int[] cell = cells[i];
            cell[1] = cell[1] + 1;
        }
    }
}
